package cn.abcsys.cloud.devops.web.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.alibaba.fastjson.JSONArray;

import cn.abcsys.cloud.devops.web.constant.Status;
import cn.abcsys.cloud.devops.web.entity.Authority;
import cn.abcsys.cloud.devops.web.entity.Auths;
import cn.abcsys.cloud.devops.web.entity.Env;
import cn.abcsys.cloud.devops.web.entity.User;
import cn.abcsys.cloud.devops.web.ldap.LdapAnon;
import cn.abcsys.cloud.devops.web.model.LoginModel;
import cn.abcsys.cloud.devops.web.service.AuthorityService;
import cn.abcsys.cloud.devops.web.service.ProjectService;
import cn.abcsys.cloud.devops.web.service.UserService;
import cn.abcsys.cloud.devops.web.util.HashUtil;
import cn.abcsys.cloud.devops.web.util.LoginUserCache;
import cn.abcsys.cloud.devops.web.util.Result;
import net.sf.json.JSONObject;

/**
 * @author xzg
 *
 */
@Controller
public class LoginEnvController {
	private static final Logger LOGGER = Logger.getLogger(LoginEnvController.class);
	@Resource
	private UserService userService;
	@Resource
	private LdapAnon ldapAnon;
	@Resource
	private AuthorityService authorityService;
	@Resource
	private ProjectService projectservice;
	
	@RequestMapping(value="/login.do",method={RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Result login(HttpServletRequest request, HttpServletResponse response, LoginModel loginRequestModel,
			RedirectAttributes redirectAttributes) {
		LOGGER.info("【" + loginRequestModel.getUserName() + "】尝试登录");
		User user=new User();
		Result result = new Result();
		List<Authority>	authList = null;//权限列表
		List<Authority>	buttonList = null;//按钮列表
		List<Env> envList = null;//环境列表
		List<Auths> auths = new ArrayList<Auths>();//转换对象
		Map<String,Object> mapData = new HashMap<String,Object>();
		// 判断验证码的session是否过期
		if (loginRequestModel.getVercode() == null || request.getSession().getAttribute("rand") == null) {
			result.setMessage("验证码失效");
			result.setSuccess(false);
			return result;
		} 
		
		//【二】：判断验证码是否正确
		String captcha = (String) request.getSession().getAttribute("rand");
		if (!loginRequestModel.getVercode().toLowerCase().equals(captcha.toLowerCase())) {
			result.setMessage("验证码不正确！");
			result.setSuccess(false);
			return result;
		} 
		
		//默认信息为失败
		int iResult = ldapAnon.authenricate(loginRequestModel.getUserName(), loginRequestModel.getPassword());
		
		if (iResult < 0 || (iResult != 0 && iResult!=1) ) {
			result.setMessage("账号或密码错误！");
			result.setSuccess(false);
			return result;
		}
		//根据用户ID获取用户信息 
		try {
			user = userService.getUserByUid(loginRequestModel.getUserName());
		} catch (Exception e) {
			LOGGER.error("check user login by userName["+loginRequestModel.getUserName()+"] falied!", e);
			result.setMessage("用户登录失败，数据库连接异常！");
			result.setSuccess(false);
			return result;
		}
		//用户不存在
		if (user == null) {
			LOGGER.error("用户不存在！");
			result.setMessage("用户不存在！");
			result.setSuccess(false);
			return result;
		}
		//用户密码错误
		boolean isEqual = HashUtil.md5Hash(loginRequestModel.getPassword()).equals(user.getUserPass());
		//如果ldap认证通过（1 == iResult），数据库密码和ldap密码不一致,则更新数据库密码  1 == iResult 
		if(0 == iResult && !isEqual) {//0表示未开启ldap认证
			LOGGER.error("用户密码错误！");
			result.setMessage("用户密码错误");
			result.setSuccess(false);
			return result;
		}else if(1 == iResult){
			//ldap认证成功直接更改数据库中的密码
			user.setUserPass(HashUtil.md5Hash(loginRequestModel.getPassword()));
		    try {
				userService.updateUserByUserId(user);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				LOGGER.error("用户信息更新失败！");
				e.printStackTrace();
			}
		}else if(0 != iResult && 1 != iResult){//ldap认证失败
			result.setMessage("ldap用户密码认证错误");
			result.setSuccess(false);
			return result;
		}
		//用户被冻结
		if(user != null && user.getUserStatus() == Status.USER.FROZEN.ordinal()){
			LOGGER.warn("登录失败：该用户已被冻结！");
			result.setMessage("该用户已被冻结,请联系管理员！");
			result.setSuccess(false);
			return result;
		}
		//用户账号已作废
		if(user != null && user.getUserStatus() == Status.USER.DELETE.ordinal()){
			LOGGER.warn("登录失败：该用户账号已作废！");
			result.setMessage("该用户账号已作废,请联系管理员！");
			result.setSuccess(false);
			return result;
		}
		String path = request.getContextPath();
		String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ path + "/";
		
		//用户登录成功，设置用户状态为登录状态()
		try {
			user.setUserLogingSessionId(request.getSession().getId());
			user.setLoginStatus((byte) 1);
			userService.updateUserByUserId(user);
		} catch (Exception e) {
			LOGGER.error("get user by username["+loginRequestModel.getUserName()+"] falied!", e);
			result.setMessage("用户登录失败，数据库连接异常！");
			result.setSuccess(false);
			return result;
		}
		request.getSession().setAttribute("user", user);
		request.getSession().setAttribute("basePath", basePath);
		LoginUserCache.USER_ID = user.getUserId();
		LOGGER.info(loginRequestModel.getUserName() + "登录成功");
		//条件存储
		Map<String,Integer> map = new HashMap<String,Integer>();
		//返回对应的环境列表以供选择
		envList = userService.getEnv(user);
		Integer envermentId = null == envList.get(0).getEnvId()? user.getDefaultEnvId():envList.get(0).getEnvId();
		request.getSession().setAttribute("envId", envermentId);
		//如果用户时超级管理员，那么他和进入和环境变量无关
			if(1 == user.getIsAdmin()){
				//超级管理员的roleId为1,action为1菜单权限，为3为按钮权限
				map.put("roleId", 1);
				map.put("action", 1);
				authList = authorityService.getAdminRoleAuths(map);
				//清空map集合条件
				map.clear();
				map.put("roleId", 1);
				map.put("action", 3);
				buttonList = authorityService.getAdminRoleAuths(map);
			}else{//如果不是超级管理员则需要取得默认环境的角色权限
					//1，首先取得用户默认的环境ID
					if(0 == envList.size())
						return new Result(false, "该用户无可用环境请与管理员联系");
//					Integer envermentId = null == envList.get(0).getEnvId()? user.getDefaultEnvId():envList.get(0).getEnvId();
//					request.getSession().setAttribute("envId", envermentId);
					if(null == envermentId){
						result.setMessage("该用户无可用环境请与管理员联系");
						result.setSuccess(false);
						return result;
					}
					map.clear();//清空参数
					//编辑查询条件
					map.put("userId", user.getUserId());
					map.put("envId",envermentId);
					//2,根据环境和用户得到该用户在默认环境中角色最大的权限
					authList =  authorityService.getUserRoleAuths(map);
					/*if(0 == envList.size()){
						result.setMessage("该用户不存在相应的环境");
						result.setSuccess(false);
						return result;
					}*/
					buttonList = authorityService.getUserButtonAuths(map);
				}
			//如果没有取得相应的权限信息，则告知前端页面相应的情况
			//if(null == authList || 0 == authList.size() || 0 == buttonList.size()){
				if(null == authList || 0 == authList.size()){
					result.setMessage("该用户还没有相应的权限，请联系上级管理员！！");
					result.setSuccess(false);
					return result;
			}
			//只做二级菜单处理、菜单级别的权限
			for(int j=0;j<authList.size();j++){
				JSONArray child = new JSONArray();
				Authority authority = authList.get(j);
				Auths auth = new Auths();
				auth.setId(authority.getAuthorityId());
				//换成remark测试
				auth.setActionUrl(authority.getAuthorityRelativeUrl());
				auth.setName(authority.getAuthorityName());
				auth.setParentId(authority.getAuthorityParentId());
				auth.setPriority(authority.getAuthorityType());
				//二级菜单作为一级菜单的子节点
				if(2 == authority.getAuthorityType())
					continue;
				//一级菜单需要封装二级菜单,得到子节点
				for(int i=0;i<authList.size();i++){
					Authority authorityCh =authList.get(i);
					Auths authCh = new Auths();
					authCh.setId(authorityCh.getAuthorityId());
					//Remarks
					authCh.setActionUrl(authorityCh.getAuthorityRelativeUrl());
					authCh.setName(authorityCh.getAuthorityName());
					authCh.setParentId(authorityCh.getAuthorityParentId());
					authCh.setPriority(authorityCh.getAuthorityType());
					//把所有上级id相同的封装起来
					if( authority.getAuthorityId() == authorityCh.getAuthorityParentId())
						child.add(JSONObject.fromObject(authCh));
				}
				if(0 != child.size())
					auth.setChildren(child);
				auths.add(auth);
			}
		
		mapData.put("envList", envList);//环境数据
		mapData.put("user", user);
		mapData.put("buttonList", buttonList);//按钮信息
		mapData.put("auths", auths);//菜单权限信息	
		//环境变量保存在session中
		request.getSession().setAttribute("envlist", envList);
		//存储默认区域0：北京
		request.getSession().setAttribute("areaFlag", "0");
		//返回环境列表和权限列表
		result.setMessage("登录成功!");
		result.setSuccess(true);
		result.setData(mapData);
		return result;
	}
	
	/**
	 * 初始登录后请求url，环境为默认环境。如果是超级管理员则无视环境，
	 * 展示所有可操作的url
	 * @param request
	 * @param envId
	 * @return
	 */
	@RequestMapping(value="/getInitUrl",method={RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Result getUrl(HttpServletRequest request,@RequestBody Map<String,Integer> env){
		Result result = new Result();
		List<Authority>	authList = null;//权限列表
		List<Authority>	buttonList = null;//按钮列表
		List<Auths> auths = new ArrayList<Auths>();//转换对象
		Map<String,List<?>> mapData = new HashMap<String,List<?>>();
		User user = null;
		Integer envId = env.get("envId");
		
		HttpSession session = request.getSession();
		user = (User) session.getAttribute("user");
		if(null == user){
			result.setMessage("会话信息失效,请重新登录!");
			result.setSuccess(false);
			return result;
		}
				//条件存储
				Map<String,Integer> map = new HashMap<String,Integer>();
				//返回对应的环境列表以供选择
				//如果用户时超级管理员，那么他和进入和环境变量无关
					if(1 == user.getIsAdmin()){
						//超级管理员的roleId为1,action为1菜单权限，为3为按钮权限
						map.put("roleId", 1);
						map.put("action", 1);
						authList = authorityService.getAdminRoleAuths(map);
						//清空map集合条件
						map.clear();
						map.put("roleId", 1);
						map.put("action", 3);
						buttonList = authorityService.getAdminRoleAuths(map);
					}else{//如果不是超级管理员则需要取得默认环境的角色权限
						map.clear();//清空参数
						//编辑查询条件
						map.put("userId", user.getUserId());
						map.put("envId",envId);
						//2,根据环境和用户得到该用户在默认环境中角色最大的权限
						authList =  authorityService.getUserRoleAuths(map);
						/*if(0 == envList.size()){
							result.setMessage("该用户不存在相应的环境");
							result.setSuccess(false);
							return result;
						}*/
						buttonList = authorityService.getUserButtonAuths(map);
					}
					//如果没有取得相应的权限信息，则告知前端页面相应的情况
					if(null == authList || 0 == authList.size() || 0 == buttonList.size()){
							result.setMessage("该用户还没有相应的权限，请联系上级管理员！！");
							result.setSuccess(false);
							return result;
					}
					//只做二级菜单处理、菜单级别的权限
					for(int j=0;j<authList.size();j++){
						JSONArray child = new JSONArray();
						Authority authority = authList.get(j);
						Auths auth = new Auths();
						auth.setId(authority.getAuthorityId());
						//换成remark测试
						auth.setActionUrl(authority.getAuthorityRelativeUrl());
						auth.setName(authority.getAuthorityName());
						auth.setParentId(authority.getAuthorityParentId());
						auth.setPriority(authority.getAuthorityType());
						//二级菜单作为一级菜单的子节点
						if(2 == authority.getAuthorityType())
							continue;
						//一级菜单需要封装二级菜单,得到子节点
						for(int i=0;i<authList.size();i++){
							Authority authorityCh =authList.get(i);
							Auths authCh = new Auths();
							authCh.setId(authorityCh.getAuthorityId());
							//Remarks
							authCh.setActionUrl(authorityCh.getAuthorityRelativeUrl());
							authCh.setName(authorityCh.getAuthorityName());
							authCh.setParentId(authorityCh.getAuthorityParentId());
							authCh.setPriority(authorityCh.getAuthorityType());
							//把所有上级id相同的封装起来
							if( authority.getAuthorityId() == authorityCh.getAuthorityParentId())
								child.add(JSONObject.fromObject(authCh));
						}
						if(0 != child.size())
							auth.setChildren(child);
						auths.add(auth);
					}
				session.setAttribute("envId", envId);
				mapData.put("buttonList", buttonList);//按钮信息
				mapData.put("auths", auths);//菜单权限信息
				//返回环境列表和权限列表
				result.setMessage("登录成功!");
				result.setSuccess(true);
				result.setData(mapData);
				return result;
	}
	
	
	
	@RequestMapping(value="/getUrlInEnv.do",method={RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Result getUrlInEnv(HttpServletRequest request,@RequestParam("envId") Integer envId){
		Result result = new Result();
		User user = null;
		Map<String,Integer> map = new HashMap<String,Integer>();
		HttpSession session = request.getSession();
		 user = (User) session.getAttribute("user");
		if(null == user){
			result.setMessage("会话信息失效！");
			result.setSuccess(false);
			return result;
		}
		//如果用户时超级管理员，那么他和进入和环境变量无关
		
		//首先取得用户默认的环境ID
		if(null == envId){
			result.setMessage("请先选择可用环境");
			result.setSuccess(false);
			return result;
		}
		map.put("userId", user.getUserId());
		map.put("envId",envId);
		List<Authority>	list =  authorityService.getUserRoleAuths(map);
		if(null == list|| 0 == list.size()){
			result.setMessage("该用户还没有相应的权限，请联系上级管理员！！");
			result.setSuccess(false);
			return result;
		}
		//正常
		result.setMessage("权限列表查询成功");
		result.setSuccess(true);
		result.setData(list);
		return result;
	}
}
